/**************************************************************************************
 *  Copyright (c)  2010  Leszek Karcz, Changmin Bae.
 *  Permission is granted to copy, distribute and/or modify this document
 *  under the terms of the GNU Free Documentation License, Version 1.3
 *  or any later version published by the Free Software Foundation;
 *  with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
 *  A copy of the license is included in the section entitled "GNU
 *  Free Documentation License". 
 **************************************************************************************/
package main;
import view.*;
import data.*;
import data.tileables.*;

/**************************************************************************************
 * Author(s): Leszek Karcz, Changmin Bae
 * Gameplay class takes care of initializing gameplay and executing time events
 **************************************************************************************/
public class Gameplay extends Thread
{
	private View view;
	private Clock clock;
	private Player[] players;
	private boolean running=false;

	/**************************************************************************************
	 * Author(s): Leszek Karcz
	 * Gameplay constructor
	 **************************************************************************************/
	public Gameplay(View view, Interpreter interpreter)
	{
		this.view=view;
				
		//Hardcoded mapArray of terrain (odd = passable, even = notpassable)
		int[][] mapArray = {{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
							{1,0,0,0,1,1,1,1,1,1,1,2,1,2,1,2,1,2,1,1},
							{1,0,0,0,0,0,0,0,0,0,1,1,2,0,2,2,0,2,0,1},
							{1,0,0,0,2,2,2,0,0,0,1,1,0,2,2,2,2,2,2,1},
							{1,0,0,3,3,3,3,3,0,0,1,1,0,2,2,2,2,2,0,1},
							{1,5,7,9,2,2,2,0,0,0,1,1,0,2,2,2,2,2,0,1},
							{1,1,0,2,2,2,2,2,0,0,1,1,0,0,2,2,2,0,0,1},
							{1,1,0,2,2,2,2,2,2,0,0,0,0,3,3,3,3,3,0,1},
							{1,1,2,0,2,2,0,2,0,2,1,1,0,0,2,2,2,0,0,1},
							{1,2,1,2,1,2,1,2,1,2,1,1,0,0,2,2,2,0,0,1},
							{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}};
		//Initialize Map
		Map map = new Map(mapArray);
		
		
		
		map.putDoodadOnTile(2, 2, new AreaEffectDeath());
		map.putDoodadOnTile(2, 1, new AreaEffectHeal());
		map.putDoodadOnTile(1, 1, new AreaEffectDamage(-1));
		
		
		
		map.putDoodadOnTile(9, 6, new ItemArmorUp());
		map.putDoodadOnTile(8, 6, new ItemHealthUp());
		map.putDoodadOnTile(2, 2, new Decal("1"));
		map.putDoodadOnTile(2, 2, new Decal("0"));
		map.putDoodadOnTile(1, 1, new Decal("0"));
		map.putDoodadOnTile(9, 7, new Resources(15,100,70));
		map.putDoodadOnTile(3, 2, new Resources(1000,1000,500));
		map.putDoodadOnTile(3, 3, new Resources(500,350,0));
		map.putDoodadOnTile(6, 1, new Resources(50,5,5));
		
		//Initializes clock
		this.clock = new Clock(500);
		
		
		//test area function
		map.getArea(3, 1, 2);
		CombatManager combatMngr = new CombatManager(map);	
		
		//initialize players
		players=new Player[2];
		players[0]=new Player(0,3,1,combatMngr);
		players[1]=new Player(1,10,10,combatMngr);
		
		
		//Initialize GameplayPlayerData
		GameplayPlayerData[] gameplayPlayerData = new GameplayPlayerData[2];
		gameplayPlayerData[0] = new GameplayPlayerData(map, clock, players[0]);
		gameplayPlayerData[1] = new GameplayPlayerData(map, clock, players[1]);
		
		//Initialize OverviewData
		OverviewData overviewData = new OverviewData(players[0]);
		
		//link GameplayPlayerData to interpreter
		interpreter.addGameplay(this, gameplayPlayerData[0]);
		
		//link OverviewData to interpreter
		interpreter.addOverview(overviewData);
		
		players[0].createRally();
				
		players[0].createExplorer();
		players[0].createExplorer();
		players[0].createColonyShip();
		
		
		players[1].createRange(5, 3);
		players[1].createMelee(4, 2);
		
		
		
		//players[0].createExplorer(5,6);
		//players[0].createExplorer(8,7);
		//players[0].createExplorer(5,2);
		//players[0].createExplorer(5,2);
		
		//players[0].createExplorer(0,0);
		//players[0].createExplorer(0,0);
		//players[0].createExplorer(0,0);
		//players[0].createExplorer(0,0);
		
		
		
		
		//players[1].createExplorer(4,4);
		
		//add gameplayData to the View		
		view.addGameplay(gameplayPlayerData[0]);
		
		//add overviewData to the View		
		view.addOverview(overviewData);
		
		this.start();
	}
	
	/**************************************************************************************
	 * Author(s): Leszek Karcz
	 * gameplay loop - controls all events in game
	 **************************************************************************************/
	public void run()
	{
		while(true)
		{
			if(this.running)
			{
				//events occurring more often than 1 tick
				if(this.clock.isNext())
				{
					//execute tick gameplay events
					this.players[0].execute();
					
					//refresh view
					view.refresh(1);
				}				
			}			
			delay(1);
		}
	}
	
	/**************************************************************************************
	 * Author(s): Leszek Karcz
	 * starts the gameplay loop
	 **************************************************************************************/
	public void startGameplay()
	{
		this.running=true;
		this.clock.startClock();
	}
	
	/**************************************************************************************
	 * Author(s): Leszek Karcz
	 * stops the gameplay loop
	 **************************************************************************************/
	public void stopGameplay()
	{
		this.running=false;
		this.clock.stopClock();
	}	
	
	/**************************************************************************************
	 * Author(s): ?
	 * delays the execution by certain interval in microseconds
	 **************************************************************************************/
	private static void delay(int interval)
	{
		try
		{
			Thread.sleep(interval);
		}
		catch(InterruptedException e)
		{
			e.printStackTrace();
		}
	}
}
